package com.link.base.wechat.mpnews.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.link.core.cllog.LCLogger;
import com.link.base.wechat.basic.util.WxExceptionUtil;
import com.link.base.wechat.basic.util.WeixinHttpUtil;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.JsonUtil;
import com.link.core.util.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信公众号图文素材工具类
 *
 * @author lujiang
 * @date 2019/02/25 17:00
 */
public class ArticleUtil {
    /**
     *  上传图文素材URL
     */
    private static final String UPLOAD_ARTICLE_URL = "https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN";

    /**
     *  修改永久图文
     */
    private static final String UPDATE_ARTICLE_URL = "https://api.weixin.qq.com/cgi-bin/material/update_news?access_token=ACCESS_TOKEN";

    /**
     *  删除微信永久素材
     */
    private static final String DELETE_ARTICLE_URL = "https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=ACCESS_TOKEN";

    /**
     * 新增永久素材(上传)——新增其他类型永久素材(image、voice、video、thumb)
     */
    private static final String UPLOAD_MATERIAL_URL = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE";

    /**
     * 上传,修改图文素材
     *
     * @author lujiang
     * @date  2019/02/25 18:53
     * @param accessToken  全局唯一接口调用凭据
     * @param articlesJson 多个（一个或多个）图文toJson
     * @param rowStatus NEW（新建） OR UPDATE（修改）
     * @return
     * @throws Exception
     */
    public static Map<String,Object> upsertArticle(String accessToken,String articlesJson,String rowStatus) throws Exception {
        Map<String,Object> map = new HashMap<>(8);
        String uploadUrl = UPLOAD_ARTICLE_URL.replace("ACCESS_TOKEN", accessToken);
        String updateUrl = UPDATE_ARTICLE_URL.replace("ACCESS_TOKEN", accessToken);
        String insert = "NEW";
        String update = "UPDATE";
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.equals(rowStatus,insert)) {
            jsonObject = WeixinHttpUtil.httpRequest(uploadUrl, "POST", articlesJson);
        } else if (StringUtils.equals(rowStatus,update)) {
            jsonObject = WeixinHttpUtil.httpRequest(updateUrl, "POST", articlesJson);
        }
        String errCode = "errcode";
        int result = 0;
        if (null == jsonObject) {
            result = 0;
        } else if (null != jsonObject && StringUtils.equals(jsonObject.getString(errCode),"88000")) {
            //添加更具体的报错，此处为“没有留言权限”的报错！
            throw new ServiceException("MPNEWS-021");
        } else if (null != jsonObject && StringUtils.equals(rowStatus,insert) && StringUtils.isBlank(jsonObject.getString("media_id"))) {
            String[] exceptionArr = new String[]{jsonObject.getString(errCode), jsonObject.getString("errmsg")};
            throw new ServiceException("MPNEWS-015", exceptionArr);
        } else if (null != jsonObject && StringUtils.equals(rowStatus,update) &&  0 != jsonObject.getInteger(errCode)) {
            String[] exceptionArr = new String[]{jsonObject.getString(errCode), jsonObject.getString("errmsg")};
            throw new ServiceException("MPNEWS-016", exceptionArr);
        }
        // 请求成功
        if (null != jsonObject && StringUtils.equals(rowStatus,insert) && StringUtils.isNotBlank(jsonObject.getString("media_id"))) {
            result = 1;
            map.put("jsonObject", jsonObject.get("media_id").toString());
        } else if (null != jsonObject && StringUtils.equals(rowStatus,update) && 0 == jsonObject.getInteger(errCode)) {
            result = 1;
        }
        map.put("result",result);
        return map;
    }

    /**
     * 删除微信永久素材（材管理模块中新建的图文消息、语音、视频等素材）
     *
     * @author lujiang
     * @date  2019/02/25 18:53
     * @param accessToken  全局唯一接口调用凭据
     * @param mediaId 多个（一个或多个）图文toJson
     * @return 1成功 0失败
     * @throws Exception
     */
    public static int deleteArticle(String accessToken,String mediaId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new ServiceException("MPNEWS-001");
        }
        if (StringUtils.isBlank(mediaId)) {
            throw new ServiceException("MPNEWS-017");
        }
        String deleteUrl = DELETE_ARTICLE_URL.replace("ACCESS_TOKEN", accessToken);
        Map<String,Object> dataMap = new HashMap<>(4);
        dataMap.put("media_id",mediaId);
        String articlesJson = JsonUtil.toString(dataMap);
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(deleteUrl, "POST", articlesJson);
        WxExceptionUtil.parse(jsonObject.toJSONString());
        int result = 1;
        return result;
    }

    /**
     * 新增其他永久素材 图片（image）、语音（voice）、视频（video）和缩略图（thumb）
     *
     * @author lujiang
     * @date  2019/02/25 19:26
     * @param accessToken  全局唯一接口调用凭据
     * @param type 素材类型
     * @param fileDir 文件路径
     * @return 1成功 0失败
     * @throws Exception
     */
    public static Map<String,Object> uploadMaterial(String accessToken, String type, String fileDir) throws Exception {
        Map<String,Object> map = new HashMap<>(8);
        if (StringUtils.isBlank(accessToken)) {
            throw new ServiceException("MPNEWS-001");
        }
        if (StringUtils.isBlank(type)) {
            throw new ServiceException("MPNEWS-018");
        }
        if (StringUtils.isBlank(fileDir)) {
            throw new ServiceException("MPNEWS-019");
        }
        File file = new File(fileDir);
        String requestUrl = UPLOAD_MATERIAL_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);
        int result = 0;
        HttpPost httpPost = new HttpPost(requestUrl);
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
        httpPost.setConfig(requestConfig);
        // 设置请求实体，封装了请求参数
        HttpEntity requestEntity = MultipartEntityBuilder.create().addPart("media",
                new FileBody(file, ContentType.create("multipart/form-data", Consts.UTF_8), file.getName())).build();
        httpPost.setEntity(requestEntity);
        try {
            response = httpClient.execute(httpPost, new BasicHttpContext());
            int statusCode = 200;
            if (response.getStatusLine().getStatusCode() != statusCode) {
                result = 0;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");
                JSONObject data = JSON.parseObject(resultStr);
                //上传临时素材成功
                String errcode = "errcode";
                if (data.getString(errcode) == null) {
                    // 成功
                    result = 1;
                    String mediaId = data.getString("media_id");
                    String url = data.getString("url");
                    map.put("media_id",mediaId);
                    map.put("url",url);
                } else {
                    int errCode = data.getInteger("errcode");
                    String errMsg = data.getString("errmsg");
                    String[] exceptionArr = new String[]{type, String.valueOf(errCode), errMsg};
                    throw new ServiceException("MPNEWS-020", exceptionArr);
                }
            }
            map.put("result",result);

        } catch (IOException e) {
            LCLogger.withException(e);
        } finally {
            if (response != null) {
                try {
                    response.close();                  //释放资源
                } catch (IOException e) {
                    LCLogger.withException(e);
                }
            }
        }
        return map;
    }

}
